package com.tedu.api.io;

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 解决：RandomAccessFile解决：File无法实现读写操作
 *
 * RandomAccessFile类  随机访问文件类
 * 功能：实现"文件"、文件夹的读写操作，底层使用C语言，底层：二进制数据
 *
 * RandomAccessFile raf=new RandomAccessFile("路径+文件全称“，“rw”)
 * RandomAccessFile raf=new RandomAccessFile("路径+文件全称“，“r”)
 * 第二个参数[mode 模式]：r 模式--->该文件可以读操作
 *                     rw 模式--->该文件可以读写操作
 * 需求：实现CV  复制音乐/视频
 */
public class RandomAccessFileAPI {
    @Test
    public void testRAF() throws IOException {
    //RandomAccessFile对象创建出来---路径＋全称  |模式：“rw”
    RandomAccessFile raf=
    new RandomAccessFile("raf.txt","rw");
    //1.在 API项目文件夹下 创建 raf.txt 文件，并且实现读写操作

    //计算机 识别：二进制  0000  0000
    /**
     * 需要往raf.txt  写出一个 a 字母
     * write(整数：a--十进制)十进制 转换为计算机识别二进制
     *     范围：0~255    ASCII码  二进制 ---十进制---字母
     *                                      97      a
     *                                      98      b
     *作用：往文件中写出一个字节，抛出IO流异常：存在写出失败情况
     * 整数的低八位写出到文件中
     * 1字节==8位二进制      0000  0001        1
     *                     0000  0010        2
     *                     0000  0011        3
     *                     0000  0110        6
     * 1024字节==1KB
     * 1024KB==1MB
     * 1024MB==1G
     * 1024G==1T
     */
    raf.write(97);//写出：一个字节，识别二进制，写十进制转二进制
    raf.write(98);
    raf.write(101);
    //write方法--一个字节一个字节写出
    //关闭流   close()
    raf.close();
    }

    /**
     * read()
     * 作用：读取一个字节，返回十进制 int类型返回，如果文件读到-1，代表结束
     * 存在IO流异常：读取可能失败~~
     */
    @Test
    public void testRead() throws IOException {
    //创建对象：随机访问文件对象---只读---raf.txt文件的内容
    RandomAccessFile raf=
    new RandomAccessFile("raf.txt","r");
    int i=raf.read();//“a”---ASCII码---97
    int j=raf.read();//“b”---ASCII码---98
    int k= raf.read();//“c”---ASCII码---101
    int y= raf.read();
    System.out.println(i+" "+j+" "+k+" "+y);
    }

    /**
     * RAF类---构造器实现！读写操作---
     *        -write(数值)  read()   一个字节一个字节写出以及读入
     *  需求：复制粘贴一个音乐  【version  1---不考虑效率】
     */
    @Test
    public void testCV() throws IOException {
    //1. 原文件---”小跳蛙.mp3"---复制----操作：读入
    RandomAccessFile src=
    new RandomAccessFile("小跳蛙.mp3","r");
    //2.复制文件--“新跳蛙.mp3”--粘贴--操作：写出
    RandomAccessFile desc=
    new RandomAccessFile("新跳蛙.mp3","rw");
    //3.用于保存读取到的字节：①保存一个字节  ②-1代表文件读取到末尾
    int data=-1;
    //4.一直 从“小跳蛙.mp3”中一个字节一个字节读取---[true]
    //(data=src.read())!=-1             条件判断语句[true]
    long start=System.currentTimeMillis();
    //获取到当前系统时间毫秒数
    while((data=src.read())!=-1){//一个字节一个字节--读
        //同时一个字节一个字节写出“新跳蛙.mp3”
        desc.write(data);
    }
    long end=System.currentTimeMillis();
    System.out.println("复制粘贴花费多少："+(end-start)/1000+"秒");
    }
    /**
     * 需求：复制粘贴一个音乐【version 1---考虑效率】
     * 一个字节一个字节读取----一个字节一个字节写出【慢】
     * 100KB读取---100KB写出    【快】
     */
    @Test
    public void testCVS() throws IOException {
    //1.从API目录下"小跳蛙.mp3"---读取数据【100KB】
    RandomAccessFile src=
            new RandomAccessFile("小跳蛙.mp3","r");
    //2.从API目录下写出"效率高.mp3"---写出教程【100KB】
    RandomAccessFile desc=
    new RandomAccessFile("效率高.mp3","rw");
    //3.保存每次读取字节量:①覆盖：保存读写数据，保障数据稳定
    //                  ②没有数据：表示文件读取到末尾
    int len=-1;
    //4.效率：100KB          字节数组：byte
    byte[] data=new byte[1024*100];  //100KB
    //5. 一直  从src文件中读取数据：100KB  |read(byte[] b)  读100KB
    //5.1 src.read() 从src"小跳蛙.mp3"  100KB的读
    //5.2  src.read(byte[] data)   从src"小跳蛙.mp3"  100KB的读
    //5.3  len=src.read(byte[] data)   保存从src"小跳蛙.mp3"  100KB的读
    //5.4  (len=src.read(byte[] data))!=-1    【复制判断条件】
    //   将读到的100KB的字节数据保存len中，只要不等于-1，没有读完，一直读
    long start=System.currentTimeMillis();
    while(   (len=src.read(data))  !=-1  ){
    //同时,读文件同时，写出数据
    // write()写出一个字节【慢】
    //write(字节数组,0,-1)  写出字节数组指定的单位量【例如：100KB】
    desc.write(data,0,len);
     }
    long end=System.currentTimeMillis();
    System.out.println("100KB复制版本："+(end - start)+"毫秒数");
    //测：视频复制：100KB

    }
}
